#from iptcinfo import IPTCInfo
import commands
from types import ListType, UnicodeType, StringType
import os
import re
import pdb
import pickle
from collections import defaultdict
from kwdict import KWDict
class FDict(dict):
    """A dictionary: filename->[tagnames], e.g. {"./src/lolpics/246feline.gif":["lolcat","cat,"cheezburger","/lolpics/]}.  Attempts to keep itself synced with its source directory.  Stores a copy of itself with its images, as fdict.p -- may be invoked by specifying a directory or a fdict.p filename. """

    def __init__(self,imgsrc="./src/",deftag="",quick=False,isrecur=0):
        self._fdfname = "fdict.p"
        self.imgroot = os.path.dirname(imgsrc)
        if os.path.isfile(imgsrc):
            self.__unpickle__()
        elif os.path.isdir(imgsrc):
            self.__parsedir__() 
        
        self.__groom__()
        #if isrecur is 0:
        #    fd = FDict( os.path.join(self.imgroot,self._fdfname),isrecur=1)
        #    self.merge(fd)
        if deftag:
            self.deftag = deftag.strip()
            self.__deftag__()

    def __deftag__(self):
        if self.deftag:
            if self.deftag[0] is not "/":
                self.deftag= "/"+self.deftag
        for key in self.keys():
            self[key].append(self.deftag)

    def __unpickle__(self):
        picklefile = open(os.path.join(self.imgroot,self._fdfname),"r")
        fdictfromfile = pickle.load(picklefile)
        self.update(fdictfromfile)
        self.__groom__()
        return self
    def __stripplurals__(self):
        pass
    def __parsedir__(self):
        #DONT CALL THIS DUDE IF YOU HAVE AN FDICT, I WILL FIX!
        isimg = re.compile(".+\.(jpg|gif|png|jpeg)",re.IGNORECASE)
        images = [os.path.join(self.imgroot,fnam) for fnam in os.listdir(self.imgroot) if isimg.match(fnam)]
        print ("Found a total of "+str(len(images))+" in "+self.imgroot)
        for image in images:
            try:
                rawkws = [] #IPTCInfo(image).keywords
            except:
                rawkws = []

            self[image] = rawkws
        self.__groom__()
        return self
    def __stripnew__(self):
        for fname in self.keys():
            keys = self[fname]
            
            usertagcount = 0
            for tag in keys:
                if tag and tag[0] is not "/":                #tags that begin with a "/" are assumed to have been assigned by the program, and therefore do not cause               
                    usertagcount = usertagcount + 1  #the "new" tag to be stripped.  All other tags trigger "new" tag stripping, since their presence indicates that the files has been viewed by the user.
            if usertagcount > 1 and keys.__contains__("new"):
                self[fname].remove("new")
        return self

    def __makenew__(self):
        for fname in self.keys():
            if self[fname].__len__() is 0:
                self[fname].append("new")

    def __groom__(self):
        self.__stripnew__()
        self.__stripdupes__()
        self.__makenew__()
        self.__syncpath__()
        self.__stripplurals__()
        self.__makeKWDict__()
    def __syncpath__(self):
        for fname in self.keys():
            realpath = os.path.join(self.imgroot,os.path.basename(fname) )
            if os.path.isfile(realpath) and realpath != fname:
                tmpk = self[fname]
                #pdb.set_trace()
                del self[fname]
                self[realpath] = tmpk
            if os.path.isfile(realpath) is not True:
                #pdb.set_trace()
                del self[fname]
    def __stripdupes__(self):
        for key in self.keys():
            self[key] = list(set(self[key]) )
    def __addsrctags__(self):
        for fname in self.keys():
            livesin = os.path.dirname(fname)
            srctag = "/".join(livesin.split("/")[2:])+"/"              #WARNING, WINDOWS USERS!
        if srctag in self[fname] is not True:
            self[fname].append(srctag)
            
    def merge(self,fdict):
        for fname in fdict.keys():
            #pdb.set_trace()
            if self.__contains__(fname):
                self[fname] = list(set(fdict[fname]).union(self[fname]))
            else:
                self[fname] = fdict[fname]
        self.__groom__()
        return self

    def pickle(self):
        self.__groom__()
        openfile = open(os.path.join(self.imgroot,"fdict.p"),"w")
        pickle.dump(self,openfile)
        openfile.close()
    def __makeKWDict__(self):
        self.kwdict = KWDict(self)               
def makeKWDict(fdict):
    kwdict = defaultdict(list)
    for fname in fdict.keys():
        for key in fdict[fname]:
            kwdict[key].append(fname)
    return kwdict 

